#include "FileParser.hpp"

void FileParser::AnimationFrame(const std::string &filename, const std::string typeName, std::vector<sf::IntRect> &listIntRect)
{
	std::ifstream file(filename.c_str());

	if(file)
	{
		while(!file.eof())
		{
			std::string line;
			std::getline(file, line);

			// Check if the line is not null
				if(line == "")
					continue;

			if(boost::find_first(line, typeName + ".AddFrame"))
			{
				// Remove X.AddFrame
				boost::replace_first(line, typeName + ".AddFrame", "");

				// Remove { and }
				boost::replace_all(line, "{", "");
				boost::replace_all(line, "}", "");

				// Remove Space
				boost::trim(line);

				int value[4] = { 0, 0, 0, 0};
				int i = 0;

				for(boost::split_iterator<std::string::iterator> It = boost::make_split_iterator(line, boost::first_finder(",", boost::is_equal())); It != boost::split_iterator<std::string::iterator>(); It++)
				{
					std::istringstream iss(boost::copy_range<std::string>(*It));
					iss >> value[i];
					i++;
				}

				sf::IntRect subRect(value[0], value[1], value[2], value[3]);
				listIntRect.push_back(subRect);

			}
		}
		file.close();
	}
	else
		std::cerr << "Error : " << filename  << " not loaded ! " << std::endl;
}


void FileParser::AllValues(const std::string &filename, std::map<std::string, std::vector<std::string> > &values)
{
    std::list<std::string> lines;

    FileParser::AllLines(filename, lines);

    boost::char_separator<char> sep("-; =,'(){}");

    for(std::list<std::string>::iterator it = lines.begin(); it != lines.end(); it++)
    {
        boost::tokenizer<boost::char_separator<char> > tok(*it, sep);

        std::vector<std::string> listValues;

        for(boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin(); beg != tok.end(); beg++)
        {

          if(beg != tok.begin() && beg != tok.end())
                listValues.push_back(*beg);
        }

        if(listValues.size() != 0)
            values.insert(std::pair<std::string, std::vector<std::string> >(*tok.begin(), listValues));

    }

}

void FileParser::AllValues(const std::string &filename, std::queue<TagValues> &values)
{
    // Get Data Script
    std::list<std::string> lines;
    FileParser::AllLines(filename, lines);

    // Separator
    boost::char_separator<char> sep("-; =,'(){}");

    for(std::list<std::string>::iterator it = lines.begin(); it != lines.end(); it++)
    {
        boost::tokenizer<boost::char_separator<char> > tok(*it, sep);

        std::vector<std::string> listValues;

        for(boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin(); beg != tok.end(); beg++)
        {
            if(beg != tok.begin() && beg  != tok.end())
                listValues.push_back(*beg);
        }
            if(listValues.size() != 0)
                values.push(TagValues(*tok.begin(), listValues));

    }

}

void FileParser::AllTagValues(const std::string &filename, const std::string tagName, std::queue<TagValues> &values)
{
    // Get Data Script
    std::list<std::string> lines;
    FileParser::AllLines(filename, lines);

    // Separator
    boost::char_separator<char> sep("-; =,'(){}");

    for(std::list<std::string>::iterator it = lines.begin(); it != lines.end(); it++)
    {
        boost::tokenizer<boost::char_separator<char> > tok(*it, sep);

        std::vector<std::string> listValues;

        if(*tok.begin() == tagName)
        {
            for(boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin(); beg != tok.end(); beg++)
            {
                if(beg != tok.begin() && beg  != tok.end())
                    listValues.push_back(*beg);
            }
                if(listValues.size() != 0)
                    values.push(TagValues(*tok.begin(), listValues));
        }
    }
}

void FileParser::AllLines(const std::string &filename, std::list<std::string> &lines)
{
    std::ifstream file(filename.c_str());

    if(file)
    {
        while(!file.eof())
        {
            std::string line;
            std::getline(file, line);

            if(line == "")
                continue;

            lines.push_back(line);
        }
    }
    else
        std::cout <<  filename << " not  loaded ! " << std::endl;

    file.close();
}


int FileParser::ValueToInt(const std::string &filename, const std::string tagName)
{
	std::ifstream file(filename.c_str());

	if(file)
	{
		while(!file.eof())
		{
			std::string line;
			std::getline(file, line);

			// Check if the line is not null
				if(line == "")
					continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);
			if(line != "")
			{
				if(*tok.begin() == tagName)
				{
					// Remove Tag
					boost::replace_first(line, tagName, "");

					// Remove = (equal)
					boost::replace_all(line, "=", "");

					// Remove Space
					boost::trim(line);

					std::istringstream iss(line);
					int value;

					iss >> value;

					file.close();

					return value;
				}
			}
		}
		std::cerr << tagName << " not found ! " << std::endl;

		file.close();

		return 0;

	}
	else
		std::cerr << "Error : " << filename << " not loaded ! " << std::endl;

}

float FileParser::ValueToFloat(const std::string &filename, const std::string tagName)
{
	std::ifstream file(filename.c_str());

	if(file)
	{
		while(!file.eof())
		{
			std::string line;
			std::getline(file, line);

			// Check if the line is not null
				if(line == "")
					continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);

			if(*tok.begin() == tagName)
			{
				// Remove Tag
				boost::replace_first(line, tagName, "");

				// Remove = (equal)
				boost::replace_all(line, "=", "");


				// Remove Space
				boost::trim(line);

				std::istringstream iss(line);
				float value;

				iss >> value;

				file.close();

				return value;
			}
		}
		std::cerr << tagName << " not found ! " << std::endl;

		file.close();

		return 0.f;
	}
	else
		std::cerr << "Error : " << filename << " not loaded ! " << std::endl;

}

std::string FileParser::ValueToString(const std::string &filename, const std::string tagName)
{

	std::ifstream file(filename.c_str());


	if(file)
	{
		while(!file.eof())
		{
			std::string line;
			std::getline(file, line);

			// Check if the line is not null
				if(line == "")
					continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);


				if(*tok.begin() == tagName)
				{
					// Remove Tag
					boost::replace_first(line, tagName, "");

					// Remove = (equal)
					boost::replace_all(line, "=", "");


					// Remove Space
					boost::trim(line);

					file.close();

					return line;
				}
		}
		std::cerr << tagName << " not found ! " << std::endl;

	  file.close();

		return "";
	}
	else
		std::cerr << "Error : " << filename << " not loaded ! " << std::endl;

}

void FileParser::Values(const std::string &filename, const std::list<std::string> &listTagName, std::map<std::string, std::string> &values)
{
	std::ifstream file(filename.c_str());

	if(file)
	{
		while(!file.eof())
		{
			std::string line;
			std::getline(file, line);

			// Check if the line is not null
				if(line == "")
					continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);

			for(std::list<std::string>::const_iterator it = listTagName.begin(); it != listTagName.end(); it++)
			{
				if(*tok.begin() == *it)
				{
					// Remove Tag
					boost::replace_first(line, *it, "");

					// Remove = (equal)
					boost::replace_all(line, "=", "");


					// Remove Space
					boost::trim(line);

					values.insert(TagValue(*it, line));

					continue;
				}
			}
		}
	  file.close();
	}
	else
		std::cerr << "Error : " << filename << " not loaded ! " << std::endl;

}

void FileParser::SetValue(const std::string &filename, const std::string tagName, const std::string &value)
{
	// Check if the file is protected
	if(!boost::ends_with(filename, ".user"))
	{
		std::cerr << "Error : this file can not be changed " << std::endl;
		return;
	}

	std::ifstream InFile(filename.c_str());

	std::string OutString = "";

	if(InFile)
	{
			while(!InFile.eof())
			{

				std::string line;
				std::getline(InFile, line);

				// Check if the line is not null
				if(line == "")
					continue;

				// Add Separator for tokenizer
				boost::char_separator<char> separator(" ");

				// Tokenizer the current line
				boost::tokenizer<boost::char_separator<char> > tok(line, separator);

				if(*tok.begin() == tagName)
				{
					OutString += tagName;
					OutString += " = ";
					OutString += value;
					OutString += "\n";
				}
				else
				{
					OutString += line;
					OutString += "\n";
				}


			}

		InFile.close();

	}
	else
		std::cerr << "Error : " << filename << " not found ! " << std::endl;

	std::ofstream Outfile(filename.c_str());

	Outfile << OutString;

	Outfile.close();

}

void FileParser::SetValue(const std::string &filename, const std::string tagName, const int &value)
{
	// Check if the file is protected
	if(!boost::ends_with(filename, ".user"))
	{
		std::cerr << "Error : this file can not be changed " << std::endl;
		return;
	}

	std::ifstream InFile(filename.c_str());

	std::string OutString = "";

	if(InFile)
	{

		while(!InFile.eof())
		{

			std::string line;
			std::getline(InFile, line);

			// Check if the line is not null
			if(line == "")
				continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);

			if(*tok.begin() == tagName)
			{
				OutString += tagName;
				OutString += " = ";

				 std::ostringstream oss;
				 oss << value;

			    OutString += oss.str();
				OutString += "\n";
			}
			else
			{
				OutString += line;
				OutString += "\n";
			}


		}

		InFile.close();

	}
	else
		std::cerr << "Error : " << filename << " not found ! " << std::endl;

	std::ofstream Outfile(filename.c_str());

	Outfile << OutString;

	Outfile.close();

}

void FileParser::SetValue(const std::string &filename, const std::string tagName, const float &value)
{

	// Check if the file is protected
	if(!boost::ends_with(filename, ".user"))
	{
		std::cerr << "Error : this file can not be changed " << std::endl;
		return;
	}

	std::ifstream InFile(filename.c_str());

	std::string OutString = "";

	if(InFile)
	{

		while(!InFile.eof())
		{

			std::string line;
			std::getline(InFile, line);

			// Check if the line is not null
				if(line == "")
					continue;

			// Add Separator for tokenizer
			boost::char_separator<char> separator(" ");

			// Tokenizer the current line
			boost::tokenizer<boost::char_separator<char> > tok(line, separator);

			if(*tok.begin() == tagName)
			{
				OutString += tagName;
				OutString += " = ";

				 std::ostringstream oss;
				 oss << value;

			    OutString += oss.str();
				OutString += "\n";
			}
			else
			{
				OutString += line;
				OutString += "\n";
			}


		}

		InFile.close();

	}
	else
		std::cerr << "Error : " << filename << " not found ! " << std::endl;

	std::ofstream Outfile(filename.c_str());

	Outfile << OutString;

	Outfile.close();

}

void FileParser::SetValues(const std::string &filename, std::map<std::string, std::string> &values)
{
	// Check if the file is protected
	if(!boost::ends_with(filename, ".user"))
	{
		std::cerr << "Error : this file can not be changed " << std::endl;
		return;
	}

	std::ifstream inFile(filename.c_str());

	std::string outString = "";
	if(inFile)
	{
		while(!inFile.eof())
			{

				std::string line;
				std::getline(inFile, line);

				// Check if the line is not null
					if(line == "")
						continue;

				// Add Separator for tokenizer
				boost::char_separator<char> separator(" ");

				// Tokenizer the current line
				boost::tokenizer<boost::char_separator<char> > tok(line, separator);

				bool tagFound = false;

				for(std::map<std::string, std::string>::iterator it = values.begin(); it != values.end(); it++)
				{
					if(*tok.begin() == it->first)
					{
						outString += it->first;
						outString += " = ";
						outString += it->second;
						outString += "\n";
						tagFound = true;
						continue;
					}


				}

				if(!tagFound)
				{
					outString += line;
					outString += "\n";
				}


		}
		inFile.close();

	}
	else
		std::cerr << "Error : " << filename << " not found ! " << std::endl;

	std::ofstream outFile(filename.c_str());

	outFile << outString;

	outFile.close();


}

float FileParser::ToFloat(const std::string &value)
{
   std::istringstream iss(value);
   float fvalue;

   iss >> fvalue;

  return fvalue;

}

int FileParser::ToInt(const std::string &value)
{
   std::istringstream iss(value);
   int ivalue;

   iss >> ivalue;

   return ivalue;

}


std::string FileParser::ToString(const int &value)
{

	std::ostringstream oss;
	oss << value;

	return std::string(oss.str());

}

std::string FileParser::ToString(const float &value)
{
	std::ostringstream oss;
	oss << value;

	return std::string(oss.str());
}
